﻿using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;

namespace SZ.Mech
{
    public class Verb_DragonKnockback : Verb_MeleeAttack
    {
        KnockbackExtension knockbackExtension;

        protected override bool TryCastShot()
        {
            knockbackExtension = maneuver.GetModExtension<KnockbackExtension>();
            return base.TryCastShot();
        }

        protected override DamageWorker.DamageResult ApplyMeleeDamageToTarget(LocalTargetInfo target)
        {
            DamageWorker.DamageResult damageResult = new DamageWorker.DamageResult();
            DamageInfo damageInfo = new DamageInfo(this.verbProps.meleeDamageDef, tool.power, this.verbProps.meleeArmorPenetrationBase, instigator: this.caster);
            if (target.Pawn != null)
            {
                target.Pawn.TakeDamage(damageInfo);
                KnockbackFlyer(damageInfo, target.Pawn);
                if (target.Pawn.stances != null)
                {
                    target.Pawn.stances.stunner.StunFor(knockbackExtension.stunFor, this.caster);
                }
                //广域攻击
                MiaoUtility.TargetSputtering8(this.caster as Pawn, target, damageInfo, OnTarget);
            }

            void OnTarget(Pawn sputteringPawn)
            {
                KnockbackFlyer(damageInfo, sputteringPawn);
                sputteringPawn.stances.stunner.StunFor(3000, this.caster);
            }

            return damageResult;
        }

        protected void KnockbackFlyer(DamageInfo dinfo, Pawn pawn)
        {
            if (pawn.Spawned)
            {
                Thing instigator = dinfo.Instigator;//发起攻击者
                //DamageKnockbackDef damageKnockbackDef = this.def as DamageKnockbackDef;
                if (instigator != null && instigator.Spawned && instigator.Map == pawn.Map)
                {
                    Vector3 vector = instigator.DrawPos;
                    float num = Rand.Value * 10;
                    Vector3 vector2 = (pawn.DrawPos - vector);
                    Map map = pawn.Map;
                    Vector3 vector3 = pawn.DrawPos;


                    {//计算推动
                        vector2.y = 0f;
                        vector2 = vector2.normalized;
                        if (vector2.x == 0f && vector2.z == 0f)
                        {
                            return;
                        }
                        Vector3 vector4 = vector2;
                        Vector3 drawPos = pawn.DrawPos;
                        int num2 = 0;
                        while (Vector3.Distance(drawPos, vector3) < num - (float)num2)
                        {
                            float num3 = Mathf.Abs(vector4.x);
                            float num4 = Mathf.Abs(vector4.y);
                            float num5 = Mathf.Abs(vector4.z);
                            while (num3 >= 1f || num4 >= 1f || num5 >= 1f)
                            {
                                bool flag = false;
                                if (num3 >= 1f && num3 >= num4 && num3 >= num5)
                                {
                                    float x = vector3.x;
                                    vector3.x += (float)((int)Mathf.Sign(vector2.x));
                                    vector4.x -= Mathf.Sign(vector2.x);
                                    if (GenGrid.InBounds(IntVec3Utility.ToIntVec3(vector3), map) && !GenGrid.Impassable(IntVec3Utility.ToIntVec3(vector3), map))
                                    {
                                        flag = true;
                                    }
                                    else
                                    {
                                        vector3.x = x;
                                        num2++;
                                    }
                                }
                                else if (num4 >= 1f && num4 >= num3 && num4 >= num5)
                                {
                                    float y = vector3.y;
                                    vector3.y += (float)((int)Mathf.Sign(vector2.y));
                                    vector4.y -= Mathf.Sign(vector2.y);
                                    if (GenGrid.InBounds(IntVec3Utility.ToIntVec3(vector3), map) && !GenGrid.Impassable(IntVec3Utility.ToIntVec3(vector3), map))
                                    {
                                        flag = true;
                                    }
                                    else
                                    {
                                        vector3.y = y;
                                        num2++;
                                    }
                                }
                                else if (num5 >= 1f && num5 >= num4 && num5 >= num3)
                                {
                                    float z = vector3.z;
                                    vector3.z += (float)((int)Mathf.Sign(vector2.z));
                                    vector4.z -= Mathf.Sign(vector2.z);
                                    if (GenGrid.InBounds(IntVec3Utility.ToIntVec3(vector3), map) && !GenGrid.Impassable(IntVec3Utility.ToIntVec3(vector3), map))
                                    {
                                        flag = true;
                                    }
                                    else
                                    {
                                        vector3.z = z;
                                        num2++;
                                    }
                                }
                                num3 = Mathf.Abs(vector4.x);
                                num4 = Mathf.Abs(vector4.y);
                                num5 = Mathf.Abs(vector4.z);
                                if (!flag)
                                {
                                    break;
                                }
                            }
                            vector4 += vector2;
                        }
                    }



                    PawnFlyer pawnFlyer = PawnFlyer.MakeFlyer(SZ_DefOf.PawnKnockback, pawn, IntVec3Utility.ToIntVec3(vector3), null, null, false);
                    if (pawnFlyer != null)
                    {
                        if (pawnFlyer is PawnKnockback pawnKnockback)
                        {

                            //PawnKnockback pawnKnockback = pawnFlyer as PawnKnockback;
                            //if (pawnKnockback != null)
                            //{
                            pawnKnockback.speedMultiplication = knockbackExtension.speedMultiplication;
                            pawnKnockback.heightMultiplication = knockbackExtension.heightMultiplication;//这些参数只能由Def或者扩展参数给予
                                                                   //    pawnKnockback.damageDefRef = damageKnockbackDef;
                            pawnKnockback.instigator = instigator;
                            //    pawnKnockback.centerIfNoinstigator = (damageKnockbackDef.useExplosionCenter ? Harmony_PawnKnockback.SA_Exp.Position.ToVector3() : Vector3.zero);
                            //    pawnKnockback.instigatorEquipmentDef = dinfo.Weapon;
                            pawnKnockback.adjustFlightTimeMax();
                            //}
                            GenSpawn.Spawn(pawnFlyer, IntVec3Utility.ToIntVec3(vector3), map, 0);
                        }
                    }
                }
            }
        }
    }
}
